package com.lql.queue;

/**
 * 队列
 */
public class ArrayQueue {
    public static void main(String[] args) {
        NewArrayQueue newArrayQueue = new NewArrayQueue(4);
        newArrayQueue.inQueue(1);
        newArrayQueue.inQueue(2);
        newArrayQueue.inQueue(3);
//        newArrayQueue.outQueue();
//        newArrayQueue.inQueue(4);
//        newArrayQueue.outQueue();
//        newArrayQueue.inQueue(4);

        System.out.println(newArrayQueue.showQueueHead());
        System.out.println(newArrayQueue.showQueueTail());
        newArrayQueue.showQueue();
    }
}

/**
 * 修改为环形队列，解决队列无法重复使用的问题
 * 队列满：(rear + 1) % maxSize == front
 * 队列为空：rear == front
 * 队列元素个数（rear+maxSize-front)%maxSize
 */
class NewArrayQueue {
    // 队列的最大容量
    private int maxSize;
    // 队首指针，只想队列的第一个元素，从0开始
    private int front;
    // 队尾指针，指向队列的最后一个元素的后一个位置，从0开始
    private int rear;
    // 使用一维数组模拟队列
    private int[] queue;

    public NewArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        queue = new int[maxSize];
        front = 0;
        rear = 0;
    }

    /**
     * 判断当前队列是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return rear == front;
    }

    /**
     * 判断当前队列是否已满
     *
     * @return
     */
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    /**
     * 元素出队
     *
     * @return
     */
    public int outQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空无法出队");
        }
        int value = front;
        front = (front + 1) % maxSize;
        return queue[value];
    }

    /**
     * 元素入队
     *
     * @return
     */
    public void inQueue(int n) {
        if (isFull()) {
            throw new RuntimeException("队列已满无法入队");
        }
        queue[rear] = n;
        rear = (rear + 1) % maxSize;
    }

    /**
     * 展示队列元素
     *
     * @return
     */
    public void showQueue() {
        System.out.print("元素为：");
        for (int i = front; i < front+((rear+maxSize-front)%maxSize); i++) {
            System.out.print(queue[i%maxSize]+",");
        }
    }

    /**
     * 展示队头元素
     *
     * @return
     */
    public int showQueueHead() {
        return queue[front % maxSize];
    }

    /**
     * 展示队尾元素
     *
     * @return
     */
    public int showQueueTail() {
        if (rear - 1 == -1) {
            return queue[maxSize-1];
        }
        return queue[(rear - 1) % maxSize];
    }
}